package com.study.config;

import com.study.property.ResourceProperty;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.RemoteTokenServices;
import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices;

@Configuration
//标识为资源服务器，所有发往当前服务的请求都会去请求头里找token,找不到不允许访问
@EnableResourceServer
//开启方法级权限控制
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

    @Autowired
    private ResourceProperty resourceProperty;

    /**
     * 配置授权规则
     */
    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                //资源授权规则
                .antMatchers("/product/**").hasAuthority("product")
                //所有请求对应访问的用户都要有all权限范围
                .antMatchers("/**").access("#oauth2.hasScope('all')");
    }

    /**
     * 当前资源服务器的一些配置
     * @param resources
     * @throws Exception
     */
    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources.resourceId(resourceProperty.getResourceId());
        resources.tokenServices(tokenService());
    }

    /**
     * 配置资源服务器如何验证token有效性
     * 1.DefaultTokenServices
     *  如果认证服务器和资源服务器同一服务器，则直接采用此默认的服务验证
     * 2.RemoteTokenServices
     *  当认证服务器和资源服务器不是同一服务器，要使用此服务器去远程认证服务器验证
     */
    @Bean
    public ResourceServerTokenServices tokenService(){
        // 资源服务器去远程认证服务器认证token是否有效
        RemoteTokenServices service = new RemoteTokenServices();
        service.setCheckTokenEndpointUrl("http://localhost:8090/auth/oauth/check_token");
        service.setClientId("client");
        service.setClientSecret("secret");
        return service;
    }
}
